package ec.atreasure.com.core.net.rx;

import android.content.Context;

import java.io.File;
import java.util.WeakHashMap;

import ec.atreasure.com.core.net.HttpMethod;
import ec.atreasure.com.core.net.RestCreator;
import ec.atreasure.com.core.ui.AtreasureLoader;
import ec.atreasure.com.core.ui.LoaderStyle;
import io.reactivex.Observable;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;

/**
 * Description :基于retrofit、rxjava、rxandroid封装的的Rest客户端对象
 * Created by wangjin on 2019/6/25.
 * Job number：
 * Phone ：18301070822
 * Email： 120182051@qq.com
 * Person in charge : 汪渝栋
 * Leader：
 */
public final class RxRestClient {

    //请求参数
    private final WeakHashMap<String, Object> mParams;

    //请求地址
    private final String url;

    //put raw,post raw请求体
    private final RequestBody body;

    //过度动画样式
    private final LoaderStyle loaderStyle;

    //显示上下文具体到fragment或者activity
    private final Context context;

    //上传文件
    private final File uploadFile;

    RxRestClient(WeakHashMap<String, Object> mParams,
                 String url, RequestBody body,
                 LoaderStyle loaderStyle, File uploadFile,
                 Context context) {
        this.mParams = mParams;
        this.url = url;
        this.body = body;
        this.loaderStyle = loaderStyle;
        this.uploadFile = uploadFile;
        this.context = context;

    }

    /**
     * 获取RxRestClientBuilder实例
     *
     * @return
     */
    public static RxRestClientBuilder getRxRestClientBuilder() {
        return new RxRestClientBuilder();
    }

    /**
     * 发起get请求
     */
    public final Observable<String> get() {
        return request(HttpMethod.GET);
    }

    /**
     * 发起post/post raw请求
     */
    public final Observable<String> post() {
        if (body == null) {
            return request(HttpMethod.POST);
        } else {
            if (!mParams.isEmpty()) {
                throw new RuntimeException("params is must be null!");
            }
            return request(HttpMethod.POST_RAW);
        }
    }

    /**
     * 发起put/put raw请求
     */
    public final Observable<String> put() {
        if (body == null) {
            return request(HttpMethod.PUT);
        } else {
            if (!mParams.isEmpty()) {
                throw new RuntimeException("params is must be null!");
            }
            return request(HttpMethod.PUT_RAW);
        }
    }

    /**
     * 发起delete请求
     */
    public final Observable<String> delete() {
        return request(HttpMethod.DELETE);
    }

    /**
     * 发起下载文件请求
     */
    public final Observable<ResponseBody> download() {
        //TODO 下载相关逻辑调用，基于原有retrofit的restservice移植，具体逻辑已经实现
        return RestCreator.getRxRestService().download(url, mParams);
    }

    /**
     * 发起上传文件请求
     */
    public final Observable<String> upload() {
        return request(HttpMethod.UPLOAD);
    }

    /**
     * 发起网络请求返回Observable被观察者对象
     *
     * @param method
     * @return
     */
    private Observable<String> request(HttpMethod method) {
        final RxRestService restService = RestCreator.getRxRestService();
        Observable<String> observable = null;

        if (loaderStyle != null) {
            AtreasureLoader.showLoading(context, loaderStyle);
        }

        switch (method) {
            case GET:
                observable = restService.get(url, mParams);
                break;
            case POST:
                observable = restService.post(url, mParams);
                break;
            case POST_RAW:
                observable = restService.postRaw(url, body);
                break;
            case PUT:
                observable = restService.put(url, mParams);
                break;
            case PUT_RAW:
                observable = restService.putRaw(url, body);
                break;
            case DELETE:
                observable = restService.delete(url, mParams);
                break;
            case UPLOAD:
                final RequestBody requestBody = RequestBody.
                        create(MediaType.parse(MultipartBody.FORM.toString()), uploadFile);
                final MultipartBody.Part body = MultipartBody.Part
                        .createFormData("file", uploadFile.getName(), requestBody);
                observable = restService.upload(url, body);
                break;
            default:
                break;
        }

        return observable;

    }


}
